package uit.nfcmenu.models;

import java.util.ArrayList;

import uit.nfcmenu.services.GetOrdersAsyncTask;
import uit.nfcmenu.utils.CommConstant;
import uit.nfcmenu.utils.CommUrl;
import uit.nfcmenu.utils.JSONParser;
import uit.nfcmenu.utils.NetworkHelper;
import uit.nfcmenu.utils.WebserviceHelper;

import android.content.Context;
import android.util.Log;
import android.widget.Toast;


public class DatabaseManager {
	public static final String tag = DatabaseManager.class.getSimpleName();
	
	// ===========================================
	// Fields
	// ===========================================
	protected static IDataChangeHandler mObjDataWillChanged;

	protected Context mContext;
	protected GetOrdersAsyncTask mGetDataAsyncTask;
	
	protected static DatabaseManager mInstance;	
	protected MenuAdapter mMenuAdapter;
	protected ItemAdapter mItemAdapter;
	protected OrderAdapter mOrderAdapter;
	
	protected static int mID = 0;

	// ===========================================
	// Constructors, System Methods, Event Methods
	// ===========================================
	public DatabaseManager(Context context) {
		mContext = context;
//		mGetDataAsyncTask = GetOrdersAsyncTask.getInstance(DatabaseManager.this, mContext);

		mMenuAdapter = new MenuAdapter(mContext);
		mItemAdapter = new ItemAdapter(mContext);
		mOrderAdapter = new OrderAdapter(mContext);
	}
	
	public static DatabaseManager getInstance(IDataChangeHandler context) {
		mObjDataWillChanged = context;
		if (mInstance == null) {
			mInstance = new DatabaseManager(mObjDataWillChanged.getContext());
			mID = 0;
		}
		return mInstance;
	}
	
	public void notifyDataChanged() {
		mObjDataWillChanged.onDataChanged();
		
	}

	
	// -------------------------------------------
	// Controls Getting Data in background
	// -------------------------------------------
	
	public boolean start() {
		mGetDataAsyncTask=new GetOrdersAsyncTask(this, mContext);
		if (!mGetDataAsyncTask.isRunning()) {
			try {
				mGetDataAsyncTask.execute("");
			} catch (Exception e) {
				// TODO: handle exception
				return false;
			}
		}
		return true;
	}
	
	public void stop() {
		if(mGetDataAsyncTask==null) {
			return;
		}
		mGetDataAsyncTask.stop();
		mGetDataAsyncTask=null;
	}
	// -------------------------------------------
	// Controls Network
	// -------------------------------------------

	public boolean postOrder(OrderModel order) {
		String url = CommUrl.createUrlPostOrder(order.getItemID(), order.getStatus(), 
				order.getTableNo(), order.getQuantity(), order.getComment());
		String response = WebserviceHelper.callWS(url);
		return CommConstant.GET_DATA_SUCCESS.equals(response);
	}

	

	public void updateMenuToDB(ArrayList<MenuModel> arrayMenuList) {
		// TODO Auto-generated method stub
		for (MenuModel menu : arrayMenuList) {
			mMenuAdapter.updateMenuModel(menu);// TODO
			//mMenuAdapter.updateMenuModel(menu);
		}
	}

	public ArrayList<MenuModel> selectMenus() {
		// TODO Auto-generated method stub
		return mMenuAdapter.selectAll();
//		return mGetDataAsyncTask.getMenu();
	}

	public void insertOrderStates(ArrayList<OrderModel> models) {
		// TODO Auto-generated method stub
		Log.i(tag, "insertOrderStates(orders)");
		for (OrderModel model : models) {
			mOrderAdapter.insertOrderModel(model);
		}
	}

	public ArrayList<ItemModel> selectItems() {
		// TODO Auto-generated method stub
		return null;
	}

	public ArrayList<OrderModel> selectOrders() {
		// TODO Auto-generated method stub
		return null;
	}

	/**
	 * Get and update to db all foods and drinks
	 * @return
	 */
	public void getAllFoodsAndDrinksFromServer() {
		// TODO Auto-generated method stub
		if (NetworkHelper.checkNetworkStatus(mContext)) {
			getAllMenuFromServer();
			getAllItemsFromServer();
			getAllOrderFromServer();
		}
	}

	public ArrayList<MenuModel> getAllMenuFromServer(){
		ArrayList<MenuModel> menus = new ArrayList<MenuModel>();
		try {
			// get stream
			//String response = WebserviceHelper.callTestInsteadWSByAssets(mContext, "visual_data/menu.json");
			String url = CommUrl.createUrlGetAllFoodsAndDrinks();
			String response = WebserviceHelper.callWS(url);
			// parse data
			menus = JSONParser.parseMenus(response);
			// insert to DB
			updateMenuToDB(menus); 
		} catch (Exception e) {
			e.printStackTrace();
		}
		// return to view
		return menus;
	}

	public ArrayList<ItemModel> getAllItemsFromServer() {
		// TODO Get data from Server and update to database
		ArrayList<ItemModel> models = new ArrayList<ItemModel>();
		try {
			// get stream
			String url = CommUrl.createUrlGetItemsStatus();
			String response = WebserviceHelper.callWS(url);
			// parse
			models = JSONParser.parseItems(response);
			// insert db
			mItemAdapter.updateAllItems(models);
		} catch (Exception e) {
			
		}
		return models;
	}
	
	public ArrayList<OrderModel> getAllOrderFromServer(){
		
		String url = CommUrl.createUrlGetOrderInServer();
		String response = WebserviceHelper.callWS(url);
		ArrayList<OrderModel> arrayOrder = JSONParser.parseOrders(response,"");
		updateOrders(arrayOrder);
		return arrayOrder;
	}

	public ArrayList<MenuModel> getAllFoodsAndDrinksInDB() {
		// TODO Get from db
		Log.i(tag, "getAllFoodsAndDrinksInDB()");
		return mMenuAdapter.selectAll();
	}
	
	/**
	 * get sub-menu in DB
	 * @param mainId
	 */
	public ArrayList<MenuModel> getMainMenusInDB() {
		// TODO Auto-generated method stub
		return mMenuAdapter.getMainMenus();
	}

	/**
	 * get sub-menu in DB
	 * @param mainId
	 */
	public ArrayList<MenuModel> getSubMenusInDB(int mainId) {
		// TODO Auto-generated method stub
		return mMenuAdapter.getSubMenu(mainId);
	}

	public void updateOrders(ArrayList<OrderModel> orders) {
		// TODO Auto-generated method stub
		if (orders != null) {
			for (OrderModel model : orders) {
				mOrderAdapter.updateOrderModel(model);
			}
		}
	}

	public ArrayList<ItemModel> getItemsByMenu(int mainId) {
		// TODO Auto-generated method stub
		ArrayList<ItemModel> models = new ArrayList<ItemModel>();
		// get subs by menu
		ArrayList<MenuModel> subMenus = mMenuAdapter.getSubMenu(mainId);
		// get all item of subs
		for (MenuModel model : subMenus) {
			models.addAll(mItemAdapter.getItemsByMenu(model.getMenuID()));
		}
		return models;
	}

	/*
	 * Item Table
	 */
	
	public ArrayList<ItemModel> getAllItemsInDB() {
		// TODO Auto-generated method stub
		return mItemAdapter.selectAll();
	}
	
	/*
	 * Order Table
	 */

	public ArrayList<OrderChef> getOrdersInDB() {
		ArrayList<OrderChef> chefs = new ArrayList<OrderChef>();
		ArrayList<OrderModel> models = mOrderAdapter.getOrdersInDB();
		for (OrderModel model : models) {
			chefs.add(new OrderChef(model));
		}
		return chefs;
	}
}
